package com.jjc.android.util

import android.R
import android.app.Activity
import android.app.Application
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.os.Process
import android.util.TypedValue
import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import com.jjc.android.App
import com.jjc.android.BuildConfig
import com.jjc.android.activity.MainActivity
import java.io.Serializable
import java.util.*
import kotlin.system.exitProcess


object GlobalActivityStack {
    private var isForceClose: Boolean = false
    private val list by lazy { LinkedList<Activity>() }
    private var foregroundActivityCount = 0

    private var mOnAppStatusListener: OnAppStatusListener? = null

    private val callback by lazy {
        object: Application.ActivityLifecycleCallbacks {
            override fun onActivityPaused(activity: Activity) {
            }

            override fun onActivityResumed(activity: Activity) {
            }

            override fun onActivityStarted(activity: Activity) {
                activityStarted(activity)
                //数值从0变到1说明是从后台切到前台
                if (foregroundActivityCount == 1) {
                    //从后台切到前台
                    mOnAppStatusListener?.onFront()
                }
                if (BuildConfig.DEBUG) {
                    val decorView = activity.window.decorView
                    val fl = decorView.findViewById<FrameLayout>(R.id.content)
                    val activityName = activity.javaClass.simpleName
                    if(!(fl.tag as? String).isNullOrEmpty()) return
                    val textView = TextView(activity, null)
                    textView.text = activityName
                    textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 8f)
                    textView.setBackgroundColor(Color.parseColor("#3f000000"))
                    textView.setTextColor(Color.parseColor("#FFFFFF"))
                    textView.setPadding(20, 5, 0, 0)
                    val params = FrameLayout.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
                    )
                    textView.layoutParams = params
                    fl.tag = activityName
                    fl.addView(textView)
                }
            }

            override fun onActivityDestroyed(activity: Activity) {
                activityDestroyed(activity)
            }

            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
            }

            override fun onActivityStopped(activity: Activity) {
                activityStopped(activity)
                if (foregroundActivityCount == 0) {
                    //从后台切到前台
                    mOnAppStatusListener?.onBack()
                }
            }

            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                activityCreated(activity)
            }
        }
    }

    fun activityDestroyed(activity: Activity) {
        list.remove(activity)
        if (list.isEmpty() && isForceClose) {
            isForceClose = false
            killSelf()
        }
    }

    fun activityStarted(activity: Activity) {
        foregroundActivityCount++
    }

    fun activityStopped(activity: Activity) {
        foregroundActivityCount--
    }

    fun activityCreated(activity: Activity){
        list.add(activity)
    }


    /**
     * 注册Activity Lifecycle callback.
     */
    @JvmStatic
    fun registerCallback(app: Application,foreListener:OnAppStatusListener? = null) {
        app.registerActivityLifecycleCallbacks(callback)
        mOnAppStatusListener = foreListener
    }

    /**
     * 取消注册Activity Lifecycle callback.
     */
    fun unregisterCallback(app: Application) {
        list.clear()
        app.unregisterActivityLifecycleCallbacks(callback)
    }

    /**
     * 返回已启动的Activity数量.
     */
    fun getRunningActivityCount(): Int {
        return list.size
    }

    /**
     * 判断Activity是否在前台
     */
    fun isForeground(): Boolean {
        return foregroundActivityCount != 0
    }

    /**
     * 获取当前Activity.
     */
    fun getCurrentActivity(): Activity? {
        if (list.isEmpty()) {
            return null
        }

        return list.last
    }

    /**
     * 关闭[clazz] Activity.
     */
    fun finish(clazz: Class<out Activity>) {
        list.reversed().forEach {
            if (it.javaClass == clazz) {
                it.finish()
                return
            }
        }
    }

    /**
     * 关闭当前Activity.
     */
    fun finishCurrent() {
        if (list.size > 0) {
            list.last.finish()
        }
    }

    /**
     * 关闭所有Activity.
     */
    fun finishAll() {
        list.reversed().forEach {
            it.finish()
        }
    }

    /**
     * 关闭除[clazz]外的所有Activity.
     */
    fun finishAllExcept(clazz: Class<out Activity>) {
        var find = false
        list.reversed().forEach {
            if (it.javaClass == clazz && !find) {
                find = true
            } else {
                it.finish()
            }
        }
    }

    /**
     * 启动[clazz],[map]是附带参数.
     */
    fun start(clazz: Class<out Activity>, map: Map<String, Serializable>? = null) {
        val currentActivity = getCurrentActivity()
        val context = App.getContext()
        val intent = Intent(context, clazz)
        map?.forEach {
            intent.putExtra(it.key, it.value)
        }

        if (currentActivity == null) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
        } else {
            currentActivity.startActivity(intent)
        }
    }

    /**
     * 通过[intent]启动Activity.
     */
    fun start(intent: Intent) {
        intent.component?.let {
            val currentActivity = getCurrentActivity()
            if (currentActivity == null) {
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                App.getContext().startActivity(intent)
            } else {
                currentActivity.startActivity(intent)
            }
        }
    }

    /**
     * 启动[clazz], [map]是附带参数，并且关闭其他所有Activity.
     */
    fun startAndFinishOthers(clazz: Class<out Activity>, map: Map<String, Serializable>? = null) {
        start(clazz, map)
        finishAllExcept(clazz)
    }

    /**
     * [intent]方式启动Activity，并且关闭其他所有Activity.
     */
    fun startAndFinishOthers(intent: Intent) {
        intent.component?.let {
            start(intent)
            finishAllExcept(Class.forName(it.className) as Class<out Activity>)
        }
    }

    fun startAndFinishOthersAndMain(intent: Intent) {
        intent.component?.let {
            start(intent)
            finishAllExceptMain(Class.forName(it.className) as Class<out Activity>)
        }
    }

    fun startAndFinishOthersAndMain(clazz: Class<out Activity>) {
        start(clazz)
        finishAllExceptMain(clazz)
    }

    fun finishAllExceptMain(clazz: Class<out Activity>) {
        var find = false
        list.reversed().forEach {
            if ((it.javaClass == clazz||it.javaClass == MainActivity::class.java  ) && !find) {
                find = true
            } else {
                it.finish()
            }
        }
    }
    /**
     * 关闭除顶部Activity外的其他所有activity.
     */
    fun finishExceptTop() {
        val last = list.last
        while (list[0] != last) {
            list[0].finish()
            list.removeAt(0)
        }
    }


    /**
     * 强制关闭Activity.
     * @param closeImmediately true:直接调用[Process.killProcess]和[exitProcess]终止进程; false:关闭
     * 已打开的Activity, 在后台终止进程.
     */
    fun forceClose(closeImmediately: Boolean = false) {
        if (closeImmediately) {
            killSelf()
        } else {
            isForceClose = true
            finishAll()
        }
    }

    private fun killSelf() {
        Process.killProcess(Process.myPid())
        exitProcess(0)
    }


    interface OnAppStatusListener {
        fun onFront()
        fun onBack()
    }
}
